{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": 1,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "gb_4qXP5ix-l",
        "outputId": "b0612bef-9870-4d38-9895-0b02b3b12313"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/\n",
            "Collecting openai\n",
            "  Downloading openai-0.23.1.tar.gz (43 kB)\n",
            "\u001b[K     |████████████████████████████████| 43 kB 871 kB/s \n",
            "\u001b[?25h  Installing build dependencies ... \u001b[?25l\u001b[?25hdone\n",
            "  Getting requirements to build wheel ... \u001b[?25l\u001b[?25hdone\n",
            "    Preparing wheel metadata ... \u001b[?25l\u001b[?25hdone\n",
            "Requirement already satisfied: requests>=2.20 in /usr/local/lib/python3.7/dist-packages (from openai) (2.23.0)\n",
            "Requirement already satisfied: pandas>=1.2.3 in /usr/local/lib/python3.7/dist-packages (from openai) (1.3.5)\n",
            "Requirement already satisfied: numpy in /usr/local/lib/python3.7/dist-packages (from openai) (1.21.6)\n",
            "Collecting pandas-stubs>=1.1.0.11\n",
            "  Downloading pandas_stubs-1.2.0.62-py3-none-any.whl (163 kB)\n",
            "\u001b[K     |████████████████████████████████| 163 kB 3.7 MB/s \n",
            "\u001b[?25hRequirement already satisfied: typing-extensions in /usr/local/lib/python3.7/dist-packages (from openai) (4.1.1)\n",
            "Requirement already satisfied: tqdm in /usr/local/lib/python3.7/dist-packages (from openai) (4.64.1)\n",
            "Requirement already satisfied: openpyxl>=3.0.7 in /usr/local/lib/python3.7/dist-packages (from openai) (3.0.10)\n",
            "Requirement already satisfied: et-xmlfile in /usr/local/lib/python3.7/dist-packages (from openpyxl>=3.0.7->openai) (1.1.0)\n",
            "Requirement already satisfied: python-dateutil>=2.7.3 in /usr/local/lib/python3.7/dist-packages (from pandas>=1.2.3->openai) (2.8.2)\n",
            "Requirement already satisfied: pytz>=2017.3 in /usr/local/lib/python3.7/dist-packages (from pandas>=1.2.3->openai) (2022.2.1)\n",
            "Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.7/dist-packages (from python-dateutil>=2.7.3->pandas>=1.2.3->openai) (1.15.0)\n",
            "Requirement already satisfied: idna<3,>=2.5 in /usr/local/lib/python3.7/dist-packages (from requests>=2.20->openai) (2.10)\n",
            "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.7/dist-packages (from requests>=2.20->openai) (2022.6.15)\n",
            "Requirement already satisfied: chardet<4,>=3.0.2 in /usr/local/lib/python3.7/dist-packages (from requests>=2.20->openai) (3.0.4)\n",
            "Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /usr/local/lib/python3.7/dist-packages (from requests>=2.20->openai) (1.24.3)\n",
            "Building wheels for collected packages: openai\n",
            "  Building wheel for openai (PEP 517) ... \u001b[?25l\u001b[?25hdone\n",
            "  Created wheel for openai: filename=openai-0.23.1-py3-none-any.whl size=54527 sha256=c439d8b711fba4e14b0a8fb6958c15a7eb19d4396b6e8f1b43ec577bd604c831\n",
            "  Stored in directory: /root/.cache/pip/wheels/5f/f5/69/860bc773610989840e34f3352d39a4651a76f509cf1610bf22\n",
            "Successfully built openai\n",
            "Installing collected packages: pandas-stubs, openai\n",
            "Successfully installed openai-0.23.1 pandas-stubs-1.2.0.62\n",
            "Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/\n",
            "Collecting google-search-results\n",
            "  Downloading google_search_results-2.4.1.tar.gz (11 kB)\n",
            "Requirement already satisfied: requests in /usr/local/lib/python3.7/dist-packages (from google-search-results) (2.23.0)\n",
            "Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /usr/local/lib/python3.7/dist-packages (from requests->google-search-results) (1.24.3)\n",
            "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.7/dist-packages (from requests->google-search-results) (2022.6.15)\n",
            "Requirement already satisfied: chardet<4,>=3.0.2 in /usr/local/lib/python3.7/dist-packages (from requests->google-search-results) (3.0.4)\n",
            "Requirement already satisfied: idna<3,>=2.5 in /usr/local/lib/python3.7/dist-packages (from requests->google-search-results) (2.10)\n",
            "Building wheels for collected packages: google-search-results\n",
            "  Building wheel for google-search-results (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
            "  Created wheel for google-search-results: filename=google_search_results-2.4.1-py3-none-any.whl size=25789 sha256=33a6f65f3783a3b9f11e612c55d4ebd0a47e312b99953400f79ee9a9d9ec5252\n",
            "  Stored in directory: /root/.cache/pip/wheels/82/a3/c5/364155118f298722dff2f79ae4dd7c91e92b433ad36d6f7e0e\n",
            "Successfully built google-search-results\n",
            "Installing collected packages: google-search-results\n",
            "Successfully installed google-search-results-2.4.1\n"
          ]
        }
      ],
      "source": [
        "import string\n",
        "import re\n",
        "\n",
        "!pip install openai\n",
        "import openai\n",
        "import urllib.request, json \n",
        "\n",
        "!pip install google-search-results\n",
        "from serpapi import GoogleSearch\n",
        "\n",
        "from IPython.utils import io\n"
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "openai.api_key = \"\" #get one from https://openai.com , first few requests are free!\n",
        "serpapi_key = \"\" #get one from https://serpapi.com , first few requests are free!"
      ],
      "metadata": {
        "id": "TgLKkNXdRsC9"
      },
      "execution_count": 2,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "k-oUiZ9jG6mW"
      },
      "execution_count": 2,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "CQa9KS_PG7Jv"
      },
      "execution_count": 2,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "_18pNbxWG7pR"
      },
      "execution_count": 2,
      "outputs": []
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "metadata": {
        "id": "aUBDH1TBVvwN"
      },
      "outputs": [],
      "source": []
    },
    {
      "cell_type": "code",
      "source": [
        "prompt = ['''Question: Who lived longer, Muhammad Ali or Alan Turing?\n",
        "Are follow up questions needed here: Yes.\n",
        "Follow up: How old was Muhammad Ali when he died?\n",
        "Intermediate answer: Muhammad Ali was 74 years old when he died.\n",
        "Follow up: How old was Alan Turing when he died?\n",
        "Intermediate answer: Alan Turing was 41 years old when he died.\n",
        "So the final answer is: Muhammad Ali \n",
        "\n",
        "Question: When was the founder of craigslist born?\n",
        "Are follow up questions needed here: Yes.\n",
        "Follow up: Who was the founder of craigslist?\n",
        "Intermediate answer: Craigslist was founded by Craig Newmark.\n",
        "Follow up: When was Craig Newmark born?\n",
        "Intermediate answer: Craig Newmark was born on December 6, 1952.\n",
        "So the final answer is: December 6, 1952\n",
        "\n",
        "Question: Who was the maternal grandfather of George Washington?\n",
        "Are follow up questions needed here: Yes.\n",
        "Follow up: Who was the mother of George Washington?\n",
        "Intermediate answer: The mother of George Washington was Mary Ball Washington.\n",
        "Follow up: Who was the father of Mary Ball Washington?\n",
        "Intermediate answer: The father of Mary Ball Washington was Joseph Ball.\n",
        "So the final answer is: Joseph Ball \n",
        "\n",
        "Question: Are both the directors of Jaws and Casino Royale from the same country? \n",
        "Are follow up questions needed here: Yes. \n",
        "Follow up: Who is the director of Jaws? \n",
        "Intermediate Answer: The director of Jaws is Steven Spielberg. \n",
        "Follow up: Where is Steven Spielberg from? \n",
        "Intermediate Answer: The United States. \n",
        "Follow up: Who is the director of Casino Royale? \n",
        "Intermediate Answer: The director of Casino Royale is Martin Campbell. \n",
        "Follow up: Where is Martin Campbell from? \n",
        "Intermediate Answer: New Zealand. \n",
        "So the final answer is: No\n",
        "\n",
        "Question: ''', \n",
        "'''\n",
        "Are follow up questions needed here:''', ]\n",
        "\n",
        "#This is a 4-shot prompt as opposed to the 1-shot prompt used in the demo video. \n"
      ],
      "metadata": {
        "id": "2fpNhKkeN_tK"
      },
      "execution_count": 24,
      "outputs": []
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "metadata": {
        "id": "2naj2Ll0i-72"
      },
      "outputs": [],
      "source": []
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "metadata": {
        "id": "pMvrBvLd5yTS"
      },
      "outputs": [],
      "source": []
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "metadata": {
        "id": "fVlLAZYEsyt_"
      },
      "outputs": [],
      "source": []
    },
    {
      "cell_type": "code",
      "execution_count": 25,
      "metadata": {
        "id": "v7q_XURGjDxE"
      },
      "outputs": [],
      "source": [
        "def promptf(question, prompt, intermediate = \"\\nIntermediate answer:\", followup = \"Follow up:\", finalans= '\\nSo the final answer is:'):\n",
        "    cur_prompt = prompt[0] +  question + prompt[1]\n",
        "\n",
        "    print(cur_prompt, end ='')\n",
        "\n",
        "    ret_text = call_gpt(cur_prompt, intermediate)\n",
        "\n",
        "    while followup in get_last_line(ret_text):\n",
        "\n",
        "      \n",
        "      cur_prompt += ret_text\n",
        "      question = extract_question(ret_text)\n",
        "      external_answer = get_answer(question)\n",
        "\n",
        "      if external_answer is not None:\n",
        "        cur_prompt += intermediate + ' ' + external_answer + '.'\n",
        "        print(intermediate + ' ' + yellowfy(external_answer) + '.', end='' )\n",
        "        ret_text = call_gpt(cur_prompt, intermediate)\n",
        "      else:\n",
        "        #We only get here in the very rare case that Google returns no answer.\n",
        "        cur_prompt += intermediate\n",
        "        print(intermediate + ' ')\n",
        "        gpt_answer = call_gpt(cur_prompt, ['\\n'+followup, finalans])\n",
        "        cur_prompt += gpt_answer\n",
        "\n",
        "    \n",
        "    if finalans not in ret_text:\n",
        "      cur_prompt += finalans\n",
        "      print(finalans, end = '')\n",
        "      ret_text = call_gpt(cur_prompt, '\\n')\n",
        "\n",
        "    return cur_prompt + ret_text\n",
        "\n",
        "def google(question):\n",
        "  params = {\n",
        "    \"api_key\": serpapi_key,\n",
        "    \"engine\": \"google\",\n",
        "    \"q\": question,\n",
        "    \"google_domain\": \"google.com\",\n",
        "    \"gl\": \"us\",\n",
        "    \"hl\": \"en\"\n",
        "  }\n",
        "\n",
        "\n",
        "  with io.capture_output() as captured: #disables prints from GoogleSearch\n",
        "    search = GoogleSearch(params)\n",
        "    res = search.get_dict()\n",
        "\n",
        "\n",
        "  \n",
        "\n",
        "  if 'answer_box' in res.keys() and 'answer' in res['answer_box'].keys():\n",
        "    toret = res['answer_box']['answer']\n",
        "  elif 'answer_box' in res.keys() and 'snippet' in res['answer_box'].keys():\n",
        "    toret = res['answer_box']['snippet']\n",
        "  elif 'answer_box' in res.keys() and 'snippet_highlighted_words' in res['answer_box'].keys():\n",
        "    toret = res['answer_box'][\"snippet_highlighted_words\"][0]\n",
        "  elif 'snippet' in res[\"organic_results\"][0].keys():\n",
        "    toret= res[\"organic_results\"][0]['snippet'] \n",
        "  else:\n",
        "    toret = None\n",
        "\n",
        "\n",
        "  return toret\n",
        "\n",
        "\n",
        "\n",
        "def get_answer(question):\n",
        "  return google(question)\n",
        "\n",
        "def call_gpt(cur_prompt, stop):\n",
        "    ans = openai.Completion.create(\n",
        "                model=\"text-davinci-002\",\n",
        "                max_tokens=256,\n",
        "                stop=stop,\n",
        "                prompt=cur_prompt,\n",
        "                temperature=0)\n",
        "    returned = ans['choices'][0]['text']\n",
        "    print( greenify(returned), end='')\n",
        "    \n",
        "\n",
        "    return returned\n",
        "\n",
        "def extract_answer(generated):\n",
        "    if '\\n' not in generated:\n",
        "        last_line =  generated\n",
        "    else: \n",
        "        last_line = generated.split('\\n')[-1]\n",
        "\n",
        "    if ':' not in last_line:\n",
        "        after_colon = last_line\n",
        "    else:\n",
        "        after_colon = generated.split(':')[-1]\n",
        "    \n",
        "    if ' ' == after_colon[0]:\n",
        "        after_colon = after_colon[1:]\n",
        "    if '.' == after_colon[-1]:\n",
        "        after_colon = after_colon[:-1]\n",
        "\n",
        "    return after_colon\n",
        "\n",
        "def extract_question(generated):\n",
        "    if '\\n' not in generated:\n",
        "        last_line =  generated\n",
        "    else: \n",
        "        last_line = generated.split('\\n')[-1]\n",
        "\n",
        "    if 'Follow up:' not in last_line:\n",
        "      print('we probably should never get here...' + generated)\n",
        "\n",
        "    if ':' not in last_line:\n",
        "        after_colon = last_line\n",
        "    else:\n",
        "        after_colon = generated.split(':')[-1]\n",
        "    \n",
        "    if ' ' == after_colon[0]:\n",
        "        after_colon = after_colon[1:]\n",
        "    if '?' != after_colon[-1]:\n",
        "        print('we probably should never get here...' + generated)\n",
        "\n",
        "    return after_colon\n",
        "\n",
        "def get_last_line(generated):\n",
        "    if '\\n' not in generated:\n",
        "        last_line =  generated\n",
        "    else: \n",
        "        last_line = generated.split('\\n')[-1]\n",
        "\n",
        "\n",
        "    return last_line\n",
        "  \n",
        "def greenify(input):\n",
        "  return \"\\x1b[102m\" + input + \"\\x1b[0m\"\n",
        "\n",
        "def yellowfy(input):\n",
        "  return \"\\x1b[106m\" + input + \"\\x1b[0m\""
      ]
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "d_52M7ReygbU"
      },
      "execution_count": 25,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "3KyUOFCz-69N"
      },
      "execution_count": 25,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "5kuSVPdwygsT"
      },
      "execution_count": 25,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "t5vuhVmxyg7I"
      },
      "execution_count": 25,
      "outputs": []
    },
    {
      "cell_type": "code",
      "execution_count": 25,
      "metadata": {
        "id": "2o6ZsPWYjHsh"
      },
      "outputs": [],
      "source": []
    },
    {
      "cell_type": "code",
      "source": [
        "question = \"What is the hometown of the reigning men's U.S. Open champion?\""
      ],
      "metadata": {
        "id": "RnnzjG5Qn7Wu"
      },
      "execution_count": 26,
      "outputs": []
    },
    {
      "cell_type": "code",
      "execution_count": 27,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "gy0mqq4rjM0v",
        "outputId": "4297ecfd-16a8-4117-dacc-188a633ba3fb"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Question: Who lived longer, Muhammad Ali or Alan Turing?\n",
            "Are follow up questions needed here: Yes.\n",
            "Follow up: How old was Muhammad Ali when he died?\n",
            "Intermediate answer: Muhammad Ali was 74 years old when he died.\n",
            "Follow up: How old was Alan Turing when he died?\n",
            "Intermediate answer: Alan Turing was 41 years old when he died.\n",
            "So the final answer is: Muhammad Ali \n",
            "\n",
            "Question: When was the founder of craigslist born?\n",
            "Are follow up questions needed here: Yes.\n",
            "Follow up: Who was the founder of craigslist?\n",
            "Intermediate answer: Craigslist was founded by Craig Newmark.\n",
            "Follow up: When was Craig Newmark born?\n",
            "Intermediate answer: Craig Newmark was born on December 6, 1952.\n",
            "So the final answer is: December 6, 1952\n",
            "\n",
            "Question: Who was the maternal grandfather of George Washington?\n",
            "Are follow up questions needed here: Yes.\n",
            "Follow up: Who was the mother of George Washington?\n",
            "Intermediate answer: The mother of George Washington was Mary Ball Washington.\n",
            "Follow up: Who was the father of Mary Ball Washington?\n",
            "Intermediate answer: The father of Mary Ball Washington was Joseph Ball.\n",
            "So the final answer is: Joseph Ball \n",
            "\n",
            "Question: Are both the directors of Jaws and Casino Royale from the same country? \n",
            "Are follow up questions needed here: Yes. \n",
            "Follow up: Who is the director of Jaws? \n",
            "Intermediate Answer: The director of Jaws is Steven Spielberg. \n",
            "Follow up: Where is Steven Spielberg from? \n",
            "Intermediate Answer: The United States. \n",
            "Follow up: Who is the director of Casino Royale? \n",
            "Intermediate Answer: The director of Casino Royale is Martin Campbell. \n",
            "Follow up: Where is Martin Campbell from? \n",
            "Intermediate Answer: New Zealand. \n",
            "So the final answer is: No\n",
            "\n",
            "Question: What is the hometown of the reigning men's U.S. Open champion?\n",
            "Are follow up questions needed here:\u001b[102m Yes.\n",
            "Follow up: Who is the reigning men's U.S. Open champion?\u001b[0m\n",
            "Intermediate answer: \u001b[106mCarlos Alcaraz\u001b[0m.\u001b[102m\n",
            "Follow up: Where is Carlos Alcaraz from?\u001b[0m\n",
            "Intermediate answer: \u001b[106mEl Palmar, Murcia, Spain\u001b[0m.\u001b[102m\n",
            "So the final answer is: El Palmar, Murcia, Spain\u001b[0m"
          ]
        }
      ],
      "source": [
        "ret = promptf(question, prompt)\n",
        "clean_ans = extract_answer(ret)\n",
        "#green background means it was generated by GPT-3\n",
        "#cyan background means it was returned by Google Search"
      ]
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "JWOHQCU2yP-z"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "jp_o-YkTyQpO"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "Code: https://github.com/ofirpress/self-ask\n",
        "\n",
        "Paper: https://ofir.io/self-ask.pdf"
      ],
      "metadata": {
        "id": "YLJnkqpuySWk"
      }
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "NlEGP9oS6GKc"
      },
      "execution_count": null,
      "outputs": []
    }
  ],
  "metadata": {
    "colab": {
      "background_execution": "on",
      "collapsed_sections": [],
      "provenance": []
    },
    "gpuClass": "standard",
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
